//
//  RoutineChecker.swift
//  GerritHermes
//
//  Created by J.Zhou on 2020/1/7.
//  Copyright © 2020 J.Zhou. All rights reserved.
//

import Foundation
import Combine

final class RoutineChecker {
    static let shared = RoutineChecker()
    private let bag = CancellableBag()
    private var timerBag = CancellableBag()
    private var pipeline: ProjectsPipeline?

    func start() {
        do {
            try Store.createTablesIfNotExsists()

            GeneralModel.shared.objectWillChange
                .debounce(for: .milliseconds(300), scheduler: DispatchQueue.main)
                .beginWith(value: ())
                .sink {
                    let model = GeneralModel.shared
                    let gerritApi = GerritApi(user: model.username, password: model.credential, baseUrl: model.gerritAddress)
                    self.verifyAccount(gerritApi)
                    self.pipeline = ProjectsPipeline(gerritApi: gerritApi)
                    self.pipeline?.update(projects: ProjectsModel.shared.projects)
                }
                .cancel(by: bag)

            ProjectsModel.shared.objectWillChange
                .debounce(for: .milliseconds(300), scheduler: DispatchQueue.main)
                .sink {
                    self.pipeline?.update(projects: ProjectsModel.shared.projects)
                }.cancel(by: bag)
        } catch let error {
            Log.error("创建数据库表失败", context: error)
            LocalNotification.send(title: "Gerrit Hermes", body: "🤢 创建数据表失败，请使用新版本或联系开发者修复")
        }
    }

    func verifyAccount(_ gerritApi: GerritApi) {
        let verifyApi = gerritApi
            .verifyAccount()
            .share()

        verifyApi
            .sink(receiveCompletion: { (completion) in
                LocalNotification.send(title: "Gerrit HTTP Credential",
                                       body: completion.failure != nil ? "Credential校验失败" : "Hermes很高兴为您服务")
                CompletionHandler.handle(completion, context: "Verify HTTP Credential")
            }, receiveValue: { _ in
            }).cancel(by: bag)
    }
}
